package com.jagochan.imchat.module.common.utils;

import cn.hutool.extra.spring.SpringUtil;
import com.jagochan.imchat.module.common.exception.BusinessException;
import com.jagochan.imchat.module.common.exception.CommonErrorEnum;
import lombok.SneakyThrows;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;

import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

public class RedissonUtil {

    private static final RedissonClient redissonClient;

    static {
        redissonClient = SpringUtil.getBean(RedissonClient.class);
    }

    @SneakyThrows
    public static <T> T executeWithLock(String key, long waitTime, TimeUnit timeUnit, Supplier<T> supplier) {
        RLock lock = redissonClient.getLock(key);
        boolean success = lock.tryLock(waitTime, timeUnit);
        if (!success) {
            throw new BusinessException(CommonErrorEnum.LOCK_LIMIT);
        }
        try {
            return supplier.get();
        } finally {
            lock.unlock();
        }
    }

    @SneakyThrows
    public static void executeWithLock(String key, Runnable runnable) {
        RLock lock = redissonClient.getLock(key);
        boolean success = lock.tryLock();
        if (!success) {
            throw new BusinessException(CommonErrorEnum.LOCK_LIMIT);
        }
        try {
            runnable.run();
        } finally {
            lock.unlock();
        }
    }

}
